package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.*;
import com.zb.mapper.ZjUserContactMapper;
import com.zb.result.PageUtil;
import com.zb.service.ZjUserContactService;
import com.zb.service.ZjUserService;
import com.zb.vo.*;
import nonapi.io.github.classgraph.json.Id;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户联系人表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-08-08
 */
@Service
public class ZjUserContactServiceImpl extends ServiceImpl<ZjUserContactMapper, ZjUserContact> implements ZjUserContactService {
    @Resource
    private ZjUserService userService;
    @Resource
    private ZjUserContactMapper userContactMapper;

    // 保存主联系人
    @Override
    public void saveMainContact(Long custAccId, Long userId, UserVo userVo) {
        ZjUserContact userContact = userContactMapper.getMainContactByUserId(userId);
        ZjUserContact contact = new ZjUserContact();
        BeanUtils.copyProperties(userVo, contact);
        contact.setUsername(userVo.getName());
        if (null != userContact) {
            contact.setId(userContact.getId());
            this.updateById(contact);
            return;
        }
        contact.setId(IdWorker.getId());
        contact.setCustAccId(custAccId);
        contact.setUserId(userId);
        contact.setMainContact(true);
        this.save(contact);
    }

    // 保存主联系人
    @Override
    public void saveMainContact(Long custAccId, Long userId, UserInfo userInfo) {
        ZjUserContact userContact = userContactMapper.getMainContactByUserId(userId);
        ZjUserContact contact = new ZjUserContact();
        BeanUtils.copyProperties(userInfo, contact);
        contact.setUsername(userInfo.getName());
        if (null != userContact) {
            contact.setId(userContact.getId());
            this.updateById(contact);
            return;
        }
        contact.setId(IdWorker.getId());
        contact.setCustAccId(custAccId);
        contact.setUserId(userId);
        contact.setMainContact(true);
        contact.setEmail("");
        this.save(contact);
    }

    // 新增或修改联系人
    @Override
    @Transactional
    public void save(Long custAccId, Long userId, UserContactVo contactVo) {
        QueryWrapper<ZjUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id", userId);
        Assert.isTrue(null != userService.getOne(userQueryWrapper), "当前账号的的数据不存在！", null);
        Assert.isNull(userContactMapper.existByPhone(userId, contactVo.getId(), contactVo.getPhone()), "当前联系人手机号已存在");

        List<ZjUserContact> updates = new ArrayList<>();

        ZjUserContact contact = new ZjUserContact();
        BeanUtil.copyProperties(contactVo, contact);
        // 获取主联系人
        ZjUserContact mainContactUser = userContactMapper.getMainContactByUserId(userId);
        if (Objects.equals(mainContactUser.getId(), contact.getId())) {
            Assert.isTrue(contact.getMainContact(), "当前联系人为主联系人，不可更改为非默认联系人");
        }
        if (!Objects.equals(mainContactUser.getId(), contact.getId()) && contact.getMainContact()) {
            ZjUserContact updateContact = new ZjUserContact();
            updateContact.setId(mainContactUser.getId());
            updateContact.setMainContact(false);
            updates.add(updateContact);
        }

        if (null != contact.getId()) {
            updates.add(contact);
        } else {
            contact.setId(IdWorker.getId());
            contact.setCustAccId(custAccId);
            contact.setUserId(userId);
            this.save(contact);
        }
        if (CollectionUtil.isNotEmpty(updates)) {
            this.updateBatchById(updates);
        }
//        wrapper.select("id");
//
//        List<String> phones = contactVos.stream().map(UserContactVo::getPhone).toList();
//        Set<String> phoneSet = new HashSet<>(phones);
//        Assert.isTrue(phones.size() == phoneSet.size(), "联系人手机号已重复["+ phones.stream().distinct().filter(vo -> phones.indexOf(vo) != phones.lastIndexOf(vo)).collect(Collectors.joining("、")) +"]");
//
//        QueryWrapper<ZjUserContact> contactQueryWrapper = new QueryWrapper<>();
//        contactQueryWrapper.select("id", "phone", "is_main_contact AS mainContact");
//        contactQueryWrapper.eq("user_id", userId);
//        List<ZjUserContact> contacts = this.list(contactQueryWrapper);
//        // 判断手机号是否重复
//        if (null != contacts && !contacts.isEmpty()) {
//            List<String> phone01s = new ArrayList<>();
//            for (UserContactVo vo : contactVos) {
//                if (null == vo.getId() && contacts.stream().anyMatch(v -> Objects.equals(vo.getPhone(), v.getPhone()))) {
//                    phone01s.add(contacts.stream().filter(v -> Objects.equals(vo.getPhone(), v.getPhone())).findFirst().get().getPhone());
//                    break;
//                }
//                if (null != vo.getId() && contacts.stream().anyMatch(v -> !Objects.equals(vo.getId(), v.getId()) && Objects.equals(vo.getPhone(), v.getPhone()))) {
//                    phone01s.add(contacts.stream().filter(v -> Objects.equals(vo.getPhone(), v.getPhone())).findFirst().get().getPhone());
//                    break;
//                }
//            }
//            Assert.isTrue(phone01s.isEmpty(), "联系人手机号已重复["+ String.join("、", phone01s)+ "]");
//        }
//
//        // 新增联系人
//        if (null == contacts || contacts.isEmpty()) {
//            // 主联系人
//            String phone = contacts.stream().filter(vo -> vo.getMainContact()).findFirst().get().getPhone();
//            List<ZjUserContact> contactList = contacts.stream().map(vo -> {
//                ZjUserContact contact = new ZjUserContact();
//                BeanUtils.copyProperties(vo, contact);
//                contact.setId(IdWorker.getId());
//                contact.setCustAccId(custAccId);
//                contact.setMainContact(Objects.equals(vo.getPhone(), phone));
//                return contact;
//            }).toList();
//            this.saveBatch(contactList);
//            return;
//        }
//        //  获取主联系人ID
//        Long mainContactId = contacts.stream().filter(ZjUserContact::getMainContact).map(ZjUserContact::getId).findFirst().get();
//        boolean isMain = true;
//        // 判断主联人是否有改变
//        for (UserContactVo vo : contactVos) {
//            if (isMain && vo.getMainContact()) {
//                isMain = false;
//                continue;
//            }
//            vo.setMainContact(false);
//        }
//        // 没有主联系人，则原来的主联系人不变
//        if (isMain) {
//            for (UserContactVo vo : contactVos) {
//                if (null != vo.getId() && Objects.equals(vo.getId(), mainContactId)) {
//                    vo.setMainContact(true);
//                    isMain = false;
//                    break;
//                }
//            }
//        }
//        List<ZjUserContact> adds = new ArrayList<>();
//        List<ZjUserContact> updates = new ArrayList<>();
//        ZjUserContact contact = null;
//        for (UserContactVo vo : contactVos) {
//            contact = new ZjUserContact();
//            BeanUtils.copyProperties(vo, contact);
//            if (null != contact.getId()) {
//                updates.add(contact);
//                continue;
//            }
//            contact.setId(IdWorker.getId());
//            contact.setCustAccId(custAccId);
//            contact.setUserId(userId);
//            adds.add(contact);
//        }
//        if (!adds.isEmpty()) {
//            this.saveBatch(adds);
//        }
//        if (!updates.isEmpty()) {
//            this.updateBatchById(updates);
//        }
    }

    // 获取用户联系人
    @Override
    public Map<String, Object> getUserContact(Long userId, UserContactSelectVo selectVo) {
        QueryWrapper<ZjUserContact> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.orderByDesc("is_main_contact", "gmt_update");
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("username", selectVo.getName());
        }
        if (StringUtils.isNotBlank(selectVo.getPhone())) {
            wrapper.like("phone", selectVo.getPhone());
        }
        PageUtil.setPageLimit(selectVo);
        Page<ZjUserContact> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        List<UserContactListVo> voList = new ArrayList<>();
        page.getRecords().forEach(t -> voList.add(UserContactListVo.beanToVo(t)));
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    // 更改主要联系人
    @Override
    public void updateMainContact(Long userId, Long id) {
        QueryWrapper<ZjUserContact> wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("user_id", userId);
        wrapper.eq("is_main_contact", true);
        ZjUserContact contact = this.getOne(wrapper);
        Assert.isTrue(null != contact, "用户ID参数[" + userId + "]的数据不存在！", null);

        wrapper = new QueryWrapper<>();
        wrapper.select("id");
        wrapper.eq("id", id);
        Assert.isTrue(null != this.getOne(wrapper), "联系人ID参数[" + id + "]的数据不存在！", null);
        Assert.isTrue(!Objects.equals(contact.getId(), id), "联系人ID参数[" + id + "]为主要联系人，不可更改或删除，请重新指定联系人", null);

        List<ZjUserContact> contactList = new ArrayList<>();
        // 旧的主要联系人
        ZjUserContact con = new ZjUserContact();
        con.setId(contact.getId());
        con.setMainContact(false);
        contactList.add(con);
        // 新的主要联系人
        con = new ZjUserContact();
        con.setId(id);
        con.setMainContact(true);
        contactList.add(con);
        this.updateBatchById(contactList);
    }

    // 批量删除联系人
    @Override
    public void deleteBatchByids(List<Long> idList) {
        ZjUserContact contact = userContactMapper.existMainContaceByIds(idList);
        Assert.isTrue(null == contact, null == contact? "" : "[" + contact.getUsername() + "、" + contact.getPhone() + "]为主联系人，不可删除或修改！", null);
        this.removeByIds(idList);
    }

    // 根据用户ID批量删除联系人
    @Override
    public void deleteBatchByUserIds(List<Long> userIdList) {
        if (null == userIdList || userIdList.isEmpty()) {
            return;
        }
        userContactMapper.deleteBatchByUserIds(userIdList);
    }

    // 分页获取用户联系人下拉数据列表
    @Override
    public Map<String, Object> pageContactSelect(Long userId, SelectVo selectVo) {
        PageUtil.setSelectPageLimit(selectVo);
        List<UserContactSelectResultVo> voList = userContactMapper.pageContactSelect(userId, selectVo);
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), userContactMapper.pageContactSelectCount(userId, selectVo), voList);
    }

    // 根据用户ID获取主要联系人
    @Override
    public ZjUserContact getMainContactByUserId(Long userId) {
        QueryWrapper<ZjUserContact> wrapper = new QueryWrapper<>();
        wrapper.select("id", "username", "phone", "email", "province", "city", "area", "town", "address");
        wrapper.eq("user_id", userId);
        wrapper.eq("is_main_contact", true);
        return this.getOne(wrapper);
    }

    // 根据用户ID查询主联系人信息
    @Override
    public List<ZjUserContact> getMainContactByUserIds(List<Long> userIds) {
        if (null == userIds || userIds.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjUserContact> wrapper = new QueryWrapper<>();
        wrapper.select("id", "user_id", "username", "phone", "email", "province", "city", "area", "town", "address");
        wrapper.in("user_id", userIds);
        wrapper.eq("is_main_contact", true); // 主联系人
        return this.list(wrapper);
    }

    // 根据手机号查询联系人是否存在
    @Override
    public Integer existByPhone(Long userId, Long id, String phone) {
        return userContactMapper.existByPhone(userId, id, phone);
    }

    // 删除联系人地址
    @Override
    public void deleteUserContactAddress(Long id) {
        ZjUserContact contact = this.getById(id);
        Assert.isTrue(null != contact, "此联系人不存在");
        Assert.isTrue(!contact.getMainContact(), "此联系人为主联系人，不允许删除");
        this.removeById(id);
    }

    // 分页获取客户下拉数据，带出所有联系人及对应的账号
    @Override
    public Map<String, Object> pageUserSelect(Long custAccId, SelectVo selectVo) {
        PageUtil.setSelectPageLimit(selectVo);
        List<ZjUserContact> userContactList = userContactMapper.pageUserSelect(custAccId, selectVo);
        if (CollectionUtil.isEmpty(userContactList)) {
            return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), 0L, new ArrayList<>());
        }
        QueryWrapper<ZjUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.select("id", "phone");
        userQueryWrapper.in("id", userContactList.stream().map(ZjUserContact::getUserId).distinct().toList());
        List<ZjUser> userList = userService.list(userQueryWrapper);

        List<SelectEmpAddressVo> voList = userContactList.stream().map(contact -> {
            SelectEmpAddressVo vo = new SelectEmpAddressVo();
            BeanUtil.copyProperties(contact, vo);
            vo.setName(contact.getUsername());
            userList.stream().filter(f -> Objects.equals(f.getId(), contact.getUserId())).findFirst().ifPresent(user -> vo.setAccountNo(user.getPhone()));
            return vo;
        }).toList();
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), userContactMapper.pageUserSelectCount(custAccId, selectVo), voList);
    }
}
